﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ServiceModel;
using System.Configuration;
using System.Activities;

namespace WPFLibraryReservation
{
    /// <summary>
    ///  Reservations.xaml 的交互逻辑
    /// </summary>
    public partial class  Reservations : Window
    {
        private ServiceHost _sh;
        private IDictionary<Guid, WorkflowApplication> _incomingRequests;
        private IDictionary<Guid, WorkflowApplication> _outgoingRequests;
        public Reservations()
        {
            InitializeComponent();
            ApplicationInterface._app = this;
            _incomingRequests = new Dictionary<Guid, WorkflowApplication>();
            _outgoingRequests = new Dictionary<Guid, WorkflowApplication>();
        }
        public ListBox GetEventListBox()
        {
            return this.lstEvents;
        }

        private void AddEvent(string szText)
        {
            lstEvents.Items.Add(szText);
        }

        private void btnRequest_Click(object sender, RoutedEventArgs e)
        {
            Dictionary<string, object> parameters = new Dictionary<string, object>
            {
                {"Author",txtAuthor.Text},
                {"Title",txtTitle.Text},
                {"ISBN",txtISBN.Text},
                {"Writer",new ListBoxTextWriter(lstEvents)}
            };
            WorkflowApplication i = new WorkflowApplication(new SendRequest(), parameters);
            _outgoingRequests.Add(i.Id, i);
            i.Run();
        }

        private void Cancel(object sender, RoutedEventArgs e)
        {
            FrameworkElement fe = sender as FrameworkElement;
            Guid id = (Guid)fe.Tag;
            ResumeBookmark(id, false);

        }

        private void Reserve(object sender, RoutedEventArgs e)
        {
            FrameworkElement fe = sender as FrameworkElement;
            Guid id = (Guid)fe.Tag;
            ResumeBookmark(id, true);
        }
        private void ResumeBookmark(Guid id, bool bReserved)
        {
            WorkflowApplication i = _incomingRequests[id];
            try
            {
                i.ResumeBookmark("GetResponse", bReserved);
            }
            catch(Exception e)
            {
                AddEvent(e.Message);
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            string adr = ConfigurationManager.AppSettings["Address"];
            lblBranch.Content = ConfigurationManager.AppSettings["Branch Name"];
            _sh = new ServiceHost(typeof(ClientService));
            string szAddress = "http://localhost:" + adr + "/ClientService";
            System.ServiceModel.Channels.Binding bBinding = new BasicHttpBinding();
            _sh.AddServiceEndpoint(typeof(ILibraryReservation), bBinding, szAddress);
            _sh.Open();
        }



        public void RequestBook(ReservationRequest request)
        {
            Dictionary<string, object> parameters = new Dictionary<string, object>{
                {"request",request},
                {"Writer",new ListBoxTextWriter(lstEvents)}
            };
            WorkflowApplication i = new WorkflowApplication(new ProcessRequest(), parameters);
            request.InstanceID = i.Id;
            _incomingRequests.Add(i.Id, i);
            i.Run();
        }

        public void RespondToRequest(ReservationResponse response)
        {
            Guid id = response.RequestID;
            WorkflowApplication i = _outgoingRequests[id];
            try
            {
                i.ResumeBookmark("GetResponse", response);
            }
            catch (Exception e2)
            {
                AddEvent(e2.Message);
            }
        }

        public void AddNewRequest(ReservationRequest request)
        {
            this.requestList.Dispatcher.BeginInvoke(new Action(() => this.requestList.Items.Add(request)));
        }

        private void Window_Unloaded(object sender, RoutedEventArgs e)
        {
            _sh.Close();
        }

    }
}
